import store from '@/store'
import api from '@/api'
const Base64 = require('js-base64').Base64
export class AgoraEduApi {
  appID = ''
  roomId = ''
  userToken = ''
  authorization = ''
  netlessAppid = ''
  // 获取声网配置
  async getLiveRoomInfo(id) {
    return await api.getLiveAgoraRoomInfo(id, res => {
      const {
        data: { config, info }
      } = res
      this.appID = config.appid
      this.authorization = `Basic ${Base64.encode(config.auth)}`
      this.netlessAppid = config.netless_appid
      store.dispatch('live/setNetlessAppid', config.netless_appid)
      store.dispatch('live/setNetlessToken', config.netless_token)
      return info
    })
  }
  // 白板配置信息
  async getAgoraNetless() {
    store.dispatch('live/setWhiteBoardStatus', true)
    api.getLiveAgoraNetless(res => {
      const { data } = res
      store.dispatch('live/setNetlessOssInfo', data)
    })
  }

  // 房间入口
  async entry(params) {
    const data = await api.entry(this.appID, params, this.authorization)
    this.roomId = data.data.roomId
    this.userToken = data.data.userToken
  }
  // login 登录教室
  async Login(params) {
    await this.entry(params)
    if (!this.appID) throw `appId is empty: ${this.appID}`
    const {
      data: { room, user, users: userList = [] }
    } = await this.getRoomInfoBy(this.roomId)

    const me = user

    const teacherState = userList.find(user => +user.role === 1)
    const course = {
      rid: room.channelName,
      roomName: room.roomName,
      channelName: room.channelName,
      roomId: room.roomId,
      roomType: room.type,
      courseState: room.courseState,
      muteAllChat: room.muteAllChat,
      isRecording: room.isRecording,
      recordId: room.recordId,
      recordingTime: room.recordingTime,
      boardId: room.boardId,
      boardToken: room.boardToken,
      lockBoard: room.lockBoard,
      teacherId: 0,
      startTime: room.startTime
    }

    if (teacherState) {
      course.teacherId = +teacherState.uid
    }

    if (me.role === 1) {
      course.teacherId = me.uid
    }

    if (params.userUuid) {
      me.uuid = params.userUuid
    }

    const coVideoUids = userList.map(it => `${it.uid}`)

    if (course.teacherId && coVideoUids.length) {
      course.coVideoUids = coVideoUids.filter(uid => `${uid}` !== `${course.teacherId}`)
    }

    const result = {
      course,
      me,
      users: userList,
      appID: this.appID,
      onlineUsers: room.onlineUsers
    }
    return result
  }

  async getCourseRecordBy(recordId, roomId, token) {
    this.userToken = token
    const data = await api.getCourseRecordBy(
      this.appID,
      roomId,
      recordId,
      this.authorization,
      token
    )
    const boardData = await this.getWhiteboardBy(roomId)
    const teacherRecord = data.data

    const recordStatus = [
      'recording',
      'finished',
      'finished_recording_to_be_download',
      'finished_download_to_be_convert',
      'finished_convert_to_be_upload'
    ]

    const result = {
      boardId: boardData.boardId,
      boardToken: boardData.boardToken,
      startTime: data.startTime,
      endTime: data.endTime,
      url: teacherRecord ? '' : teacherRecord.url,
      status: data.status,
      statusText: recordStatus[data.status]
    }
    return result
  }

  // get whiteboard token
  async getWhiteboardBy(roomId) {
    const boardData = await api.getWhiteboardBy(
      this.appID,
      roomId,
      this.authorization,
      this.userToken
    )
    return {
      boardId: boardData.data.boardId,
      boardToken: boardData.data.boardToken
    }
  }

  async fetchRoomBy(roomId) {
    if (!this.appID) throw `appId is empty: ${this.appID}`
    this.roomId = roomId
    const {
      data: { room, user, users: userList = [] }
    } = await this.getRoomInfoBy(roomId)

    const me = user

    const teacherState = userList.find(user => +user.role === 1)

    const course = {
      rid: room.channelName,
      roomName: room.roomName,
      channelName: room.channelName,
      roomId: room.roomId,
      roomType: room.type,
      courseState: room.courseState,
      muteAllChat: room.muteAllChat,
      isRecording: room.isRecording,
      recordId: room.recordId,
      recordingTime: room.recordingTime,
      boardId: room.boardId,
      boardToken: room.boardToken,
      lockBoard: room.lockBoard,
      teacherId: 0
    }

    if (teacherState) {
      course.teacherId = +teacherState.uid
    }

    if (me.role === 1) {
      course.teacherId = me.uid
    }

    const coVideoUids = userList.map(it => `${it.uid}`)

    if (course.teacherId && coVideoUids.length) {
      course.coVideoUids = coVideoUids.filter(uid => `${uid}` !== `${course.teacherId}`)
    }

    const result = {
      course,
      me,
      users: userList,
      appID: this.appID,
      onlineUsers: room.onlineUsers
    }

    return result
  }

  // get room info
  // 获取房间信息
  async getRoomInfoBy(roomId) {
    const data = await api.getRoomInfoBy(this.appID, roomId, this.authorization, this.userToken)
    let boardData = await this.getWhiteboardBy(roomId)
    return {
      data: {
        room: {
          ...data.data.room,
          boardId: boardData.boardId,
          boardToken: boardData.boardToken
        },
        users: data.data.room.coVideoUsers,
        user: data.data.user
      }
    }
  }

  // NOTE: send channel message
  // NOTE: 发送聊天消息
  async sendChannelMessage(payload) {
    const data = await api.getRoomInfoBy(this.appID, payload, this.authorization, this.userToken)
    return data
  }

  // updateRoomUser
  // 更新用户状态，老师可更新房间内所有人，学生只能更新自己
  async updateRoomUser(user) {
    const { userId, ...userAttrs } = user
    const data = await api.updateRoomUser(
      this.appID,
      this.roomId,
      userId,
      userAttrs,
      this.authorization,
      this.userToken
    )
    return {
      data
    }
  }

  // getRoomState
  // 获取用户状态
  async getRoomState(roomId) {
    const { data } = await this.getRoomInfoBy(roomId)
    const { users: rawUsers, room: rawCourse, user: me } = data

    let usersMap = rawUsers.reduce((acc, it) => {})
    const room = {
      courseState: rawCourse.courseState
    }
    const teacher = usersMap.find(it => it.role === 1)
    if (teacher) {
      room.teacherId = teacher.uid
    }
    if (me.role === 1) {
      room.teacherId = me.uid
    }
    return {
      usersMap,
      room,
      me
    }
  }

  // getCourseState
  // 获取房间状态
  async getCourseState(roomId) {
    const { data } = await this.getRoomInfoBy(roomId)
    const { users, room } = data
    const result = {
      roomName: room.roomName,
      roomId: room.roomId,
      courseState: room.courseState,
      roomType: room.type,
      muteChat: room.muteAllChat,
      recordId: room.recordId,
      recordingTime: room.recordingTime,
      isRecording: Boolean(room.isRecording),
      boardId: room.boardId,
      boardToken: room.boardToken,
      lockBoard: room.lockBoard,
      startTime: room.startTime,
      memberCount: room.onlineUsers
    }
    const teacher = users.find(it => it.role === 1)
    if (teacher) {
      result.teacherId = teacher.uid
    }
    return result
  }

  // update course
  // 更新课程状态
  async updateCourse(params) {
    const { room } = params
    const data = await api.updateCourse(
      this.appID,
      this.roomId,
      room,
      this.authorization,
      this.userToken
    )
    return {
      data
    }
  }

  // 退出房间
  async exitRoom(roomId) {
    await api.exitRoom(this.appID, roomId, this.authorization, this.userToken)
    return
  }

  // NOTE: 学生发起连麦申请
  async studentSendApply(roomId) {
    const data = await api.studentSendApply(this.appID, roomId, this.authorization, this.userToken)
    return data
  }

  // NOTE: 学生主动取消连麦申请
  async studentStopCoVideo(roomId) {
    const data = await api.studentStopCoVideo(
      this.appID,
      roomId,
      this.authorization,
      this.userToken
    )
    return data
  }

  // NOTE: 教师同意学生申请
  async teacherAcceptApply(roomId, userId) {
    const data = await api.teacherAcceptApply(
      this.appID,
      roomId,
      userId,
      this.authorization,
      this.userToken
    )
    return data
  }

  // NOTE: teacher reject apply
  // NOTE: 教师拒绝学生连麦
  async teacherRejectApply(roomId, userId) {
    const data = await api.teacherRejectApply(
      this.appID,
      roomId,
      userId,
      this.authorization,
      this.userToken
    )
    return data
  }

  // NOTE: 教师取消学生连麦
  async teacherCancelStudent(roomId, userId) {
    const data = await api.teacherCancelStudent(
      this.appID,
      roomId,
      userId,
      this.authorization,
      this.userToken
    )
    return data
  }
}
export const eduApi = new AgoraEduApi()
